#ifndef LIST_H_
#define LIST_H_

enum {
    LIST_ERROR = -1,
    LIST_SUCCESS = 0,
    LIST_END = 1
};

typedef void* list_element_t;

struct node_t;

typedef struct list_t {
    struct node_t *head;
    struct node_t *tail;
	int size;
} list;

typedef struct iterator_t {
    struct node_t *n;
} iterator;

#define LIST_FOREACH(l, it) for(list_get_head(l, it); !(list_is_end(l, it)); list_get_next(l, it))

/* initializes list */
int list_init(list *l);

/* gets list size */
int list_get_size(list *l);

/* gets the first element in the list */
int list_get_head(list *l, iterator *it);

/* gets the last element in the list */
int list_get_tail(list *l, iterator *it);

/* returns 1 for list end */
int list_is_end(list *l, iterator *it);

/* advances the iterator to the next element */
int list_get_next(list *l, iterator *it);

/* inserts a new value before it */
int list_insert_before(list *l, iterator *it, list_element_t e);

/* inserts a new value after it */
int list_insert_after(list *l, iterator *it, list_element_t e);

/* inserts a new value as the head */
int list_insert_head(list *l, list_element_t e);

/* inserts a new value as the tail */
int list_insert_tail(list *l, list_element_t e);

/* removes an element pointed by it */
int list_remove(list *l, iterator *it);

/* removes the first element */
int list_remove_head(list *l);

/* removes the last element */
int list_remove_tail(list *l);

/* returns an iterator to the specified value in list */
int list_find(list* l, list_element_t e, iterator *it);

/* destroys the list */
int list_destroy(list *l);

/* retrieves the value pointed by the iterator */
int iterator_get_value(iterator *it, list_element_t *e);

#endif /* LIST_H_ */

